/*
 * MainFrame.java
 *
 * Created on January 16, 2005, 11:20 PM
 */
package com.bff.mpd.musicjukebox.ui;

import com.bff.bjj.ui.ConnectionErrorDialog;
import com.bff.bjj.ui.LAFChangeEvent;
import com.bff.bjj.ui.UpdateSplashDialog;
import com.bff.mpd.musicjukebox.lib.JukeboxProperties;
import java.awt.Frame;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Action;
import com.bff.mpd.musicjukebox.lib.actions.NextAction;
import com.bff.mpd.musicjukebox.lib.actions.PauseAction;
import com.bff.mpd.musicjukebox.lib.actions.PlayAction;
import com.bff.mpd.musicjukebox.lib.actions.PrevAction;
import com.bff.mpd.musicjukebox.lib.actions.StopAction;
import com.bff.bjj.ui.component.BJJPanel;
import com.bff.mpd.musicjukebox.ui.components.RetractPanel;
import com.bff.mpd.musicjukebox.ui.settings.SettingsPanel;
import com.bff.mpd.utils.Utils;
import com.bff.slimserver.musicjukebox.ui.MainFramePlayer;
import com.bff.startup.StartUpProperties;
import com.bff.startup.StartupFrame;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.bff.javampd.events.ConnectionChangeEvent;
import org.bff.javampd.events.PlayerBasicChangeEvent;
import org.bff.javampd.events.PlayerChangeEvent;
import org.bff.javampd.events.PlaylistBasicChangeEvent;
import org.bff.javampd.events.PlaylistChangeEvent;
import org.bff.javampd.exception.MPDConnectionException;
import org.bff.javampd.exception.MPDException;
import org.bff.javampd.exception.MPDPlayerException;
import org.bff.javampd.exception.MPDPlaylistException;
import org.bff.javampd.objects.MPDSong;

/**
 *
 * @author  Bill
 */
public class MainFramePlayerTop extends MainFrameBase {

    private Action prevAction;
    private Action playAction;
    private Action stopAction;
    private Action pauseAction;
    private Action nextAction;
    private PlayerPanelThin playerPanelThin;
    private SongRetractInfoPanel songPanelRetract;
    private RetractPanel retractPanel;
    private boolean retracting;
    private static JFrame parent;
    private boolean currentlyRetracting;
    private ConnectionErrorDialog connectionErrorDialog;
    private JukeboxProperties jp;

    /** Creates new form MainFrame */
    public MainFramePlayerTop(SplashScreen sp) {
        super(sp);

        jp = JukeboxProperties.getInstance();

        parent = this;

        setIconImage(Utils.createImageIcon(getClass(), "/resources/mpd/bjjicontray.jpg", "bjj image").getImage());

        playerPanelThin = new PlayerPanelThin();

        playerPanel = playerPanelThin;

        add(playerPanelThin, BorderLayout.NORTH);

        songPanelRetract = new SongRetractInfoPanel();
        add(songPanelRetract, BorderLayout.EAST);

        setRetracting(true);
        songPanelRetract.setVisible(true);
        songPanelRetract.setPreferredSize(new Dimension(200, 100));
        retractPanel = new RetractPanel(songPanelRetract, RetractPanel.BOTTOM_UP);

        if (retractPanel != null) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    retractPanel.install(parent,
                            parent.getWidth() - (int) songPanelRetract.getPreferredSize().getWidth() - 25,
                            parent.getHeight() - (int) songPanelRetract.getPreferredSize().getHeight() - 25);
                }
            }).start();
        }

        try {
            getSongInfoPanel().setSongInfo(getPlaylist().getCurrentSong());
        } catch (MPDException ex) {
            Logger.getLogger(MainFramePlayerTop.class.getName()).log(Level.SEVERE, null, ex);
        }

        if (jp.isCheckForUpdate()) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        if (!jp.isVersionNotified()
                                && !jp.isDeveloper()
                                && !jp.isSnapShot()) {
                            if (!jp.getVersion().equalsIgnoreCase(jp.versionAvailable())) {
                                UpdateSplashDialog uss = new UpdateSplashDialog(parent, jp);
                                uss.setVisible(true);
                            }
                        } else {
                            if (jp.isDeveloper()) {
                                System.out.println("In developer mode, not checking for update.");
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }

        playlistActionPanel.add(getPlaylistPanel().getActionPanel());

        final StatMPDPanel sPanel = new StatMPDPanel();
        sPanel.hideRefreshBtn();
        jPanel2.add(sPanel, BorderLayout.SOUTH);

        javax.swing.Timer t = new javax.swing.Timer(5000, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                sPanel.refreshStats();
                //hack for now
                if (retractPanel != null && !isCurrentlyRetracting() && retractPanel.isMaximized()) {
                    retractPanel.setMinimized(true);
                }
            }
        });
        t.start();

        ((SettingsPanel) settingsPanel).getLAFPanel().addLAFChangeListener(this);

        JukeboxProperties.getInstance().getMPDMonitor().start();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jPanel1 = new BJJPanel();
        mainTabbedPane = super.mainTabbedPane;
        playlistTabPanel = new BJJPanel();
        playlistPanel = new PlaylistPanel();
        jPanel2 = new BJJPanel();
        songInfoMainPanel = new BJJPanel();
        jScrollPane = new javax.swing.JScrollPane();
        songInfoPanel = new SongInfoPanel();
        playlistActionPanel = new BJJPanel();
        searchTabPanel = new BJJPanel();
        searchPanel = new SearchPanel();
        artistTabPanel = new BJJPanel();
        explorerPanel = new ExplorerPanel();
        folderTabPanel = new BJJPanel();
        folderPanel = new FolderTreePanel();
        SavedPlaylistTabPanel = new javax.swing.JPanel();
        savedPlaylistPanel = new SavedPlaylistPanel();
        adminTabPanel = new BJJPanel();
        settingsPanel = new SettingsPanel();

        jMenu1.setText("Menu");
        jMenuBar1.add(jMenu1);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Bill's Jammin' Jukebox");
        addWindowFocusListener(new java.awt.event.WindowFocusListener() {
            public void windowGainedFocus(java.awt.event.WindowEvent evt) {
                MainFramePlayerTop.this.windowGainedFocus(evt);
            }
            public void windowLostFocus(java.awt.event.WindowEvent evt) {
            }
        });
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                MainFramePlayerTop.this.windowClosing(evt);
            }
        });

        jPanel1.setLayout(new java.awt.BorderLayout());

        playlistTabPanel.setBackground(java.awt.Color.lightGray);
        playlistTabPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5));
        playlistTabPanel.setPreferredSize(new java.awt.Dimension(500, 514));
        playlistTabPanel.setLayout(new java.awt.BorderLayout());

        playlistPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Playlist"));
        playlistPanel.setMinimumSize(new java.awt.Dimension(200, 200));
        playlistPanel.setPreferredSize(new java.awt.Dimension(400, 500));
        playlistTabPanel.add(playlistPanel, java.awt.BorderLayout.CENTER);

        jPanel2.setLayout(new java.awt.BorderLayout());

        songInfoMainPanel.setBackground(java.awt.Color.lightGray);
        songInfoMainPanel.setLayout(new java.awt.BorderLayout());

        jScrollPane.setBackground(java.awt.Color.lightGray);
        jScrollPane.setBorder(javax.swing.BorderFactory.createTitledBorder("Song Info"));
        jScrollPane.setPreferredSize(new java.awt.Dimension(400, 160));

        songInfoPanel.setBackground(java.awt.Color.lightGray);
        songInfoPanel.setMinimumSize(new java.awt.Dimension(400, 22));
        jScrollPane.setViewportView(songInfoPanel);

        songInfoMainPanel.add(jScrollPane, java.awt.BorderLayout.CENTER);

        jPanel2.add(songInfoMainPanel, java.awt.BorderLayout.NORTH);

        playlistActionPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Playlist Actions"));
        jPanel2.add(playlistActionPanel, java.awt.BorderLayout.CENTER);

        playlistTabPanel.add(jPanel2, java.awt.BorderLayout.EAST);

        mainTabbedPane.addTab(Utils.getMessage("TAB_PLAYLIST"), playlistTabPanel); // NOI18N

        searchTabPanel.setLayout(new java.awt.BorderLayout());
        searchTabPanel.add(searchPanel, java.awt.BorderLayout.CENTER);

        mainTabbedPane.addTab(Utils.getMessage("TAB_SEARCH"), searchTabPanel); // NOI18N

        artistTabPanel.setLayout(new java.awt.BorderLayout());
        artistTabPanel.add(explorerPanel, java.awt.BorderLayout.CENTER);

        mainTabbedPane.addTab(Utils.getMessage("TAB_EXPLORER"), artistTabPanel); // NOI18N

        folderTabPanel.setLayout(new java.awt.BorderLayout());
        folderTabPanel.add(folderPanel, java.awt.BorderLayout.CENTER);

        mainTabbedPane.addTab(Utils.getMessage("TAB_FOLDER"), folderTabPanel); // NOI18N

        SavedPlaylistTabPanel.setLayout(new java.awt.BorderLayout());
        SavedPlaylistTabPanel.add(savedPlaylistPanel, java.awt.BorderLayout.CENTER);

        mainTabbedPane.addTab(Utils.getMessage("TAB_SAVED_PLAYLISTS"), SavedPlaylistTabPanel); // NOI18N

        settingsPanel.setPreferredSize(new java.awt.Dimension(800, 600));
        adminTabPanel.add(settingsPanel);

        mainTabbedPane.addTab(Utils.getMessage("TAB_SETTINGS"), adminTabPanel); // NOI18N

        jPanel1.add(mainTabbedPane, java.awt.BorderLayout.CENTER);

        getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel SavedPlaylistTabPanel;
    private javax.swing.JPanel adminTabPanel;
    private javax.swing.JPanel artistTabPanel;
    private javax.swing.JPanel explorerPanel;
    private javax.swing.JPanel folderPanel;
    private javax.swing.JPanel folderTabPanel;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane;
    private javax.swing.JTabbedPane mainTabbedPane;
    private javax.swing.JPanel playlistActionPanel;
    private javax.swing.JPanel playlistPanel;
    private javax.swing.JPanel playlistTabPanel;
    private javax.swing.JPanel savedPlaylistPanel;
    private javax.swing.JPanel searchPanel;
    private javax.swing.JPanel searchTabPanel;
    private javax.swing.JPanel settingsPanel;
    private javax.swing.JPanel songInfoMainPanel;
    private javax.swing.JPanel songInfoPanel;
    // End of variables declaration//GEN-END:variables

    @Override
    public void playlistBasicChange(PlaylistBasicChangeEvent event) {
        switch (event.getId()) {
            case PlaylistBasicChangeEvent.SONG_CHANGED:

                try {
                    MPDSong song = getPlaylist().getCurrentSong();
                    setSongInfo(song);
                    playerPanelThin.setSong(song);

                    if (trayIcon != null) {
                        trayIcon.displayMessage(song.getArtist().getName(),
                                song.getTitle(),
                                TrayIcon.MessageType.INFO);

                    }
                } catch (MPDConnectionException ex) {
                    Logger.getLogger(MainFramePlayerTop.class.getName()).log(Level.SEVERE, null, ex);
                } catch (MPDPlaylistException ex) {
                    Logger.getLogger(MainFramePlayerTop.class.getName()).log(Level.SEVERE, null, ex);
                }

                break;
        }
    }

    private void retractPanel() {
        if (isRetracting()) {
            if (!isCurrentlyRetracting()) {
                setCurrentlyRetracting(true);
                retractPanel.toggle(true);

                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            Thread.sleep(5000);

                            if (isRetracting()) {
                                retractPanel.toggle(true);
                            }
                        } catch (InterruptedException ex) {
                            Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                        } finally {
                            setCurrentlyRetracting(false);
                            retractPanel.setMinimized(true);
                        }
                    }
                }).start();
            }
        }

    }

    @Override
    public void connectionChangeEventReceived(ConnectionChangeEvent event) {

        if (connectionErrorDialog == null) {
            connectionErrorDialog = new ConnectionErrorDialog(this);
        }

        if (event.isConnected()) {
            connectionErrorDialog.setVisible(false);
        } else {
            if (!connectionErrorDialog.isVisible()) {
                connectionErrorDialog.setVisible(true);
                connectionErrorDialog.toFront();
            }
        }
    }

    @Override
    public void playerChanged(PlayerChangeEvent event) {
        switch (event.getId()) {
            case (PlayerChangeEvent.PLAYER_SONG_SET):
                try {
                    setSongInfo(getPlayer().getCurrentSong());
                    getSongInfoPanel().setBitrate(getPlayer().getBitrate());
                } catch (MPDConnectionException ex) {
                    Logger.getLogger(MainFramePlayerTop.class.getName()).log(Level.SEVERE, null, ex);
                } catch (MPDPlayerException ex) {
                    Logger.getLogger(MainFramePlayerTop.class.getName()).log(Level.SEVERE, null, ex);
                }

                break;
        }
    }

    @Override
    public void playerBasicChange(PlayerBasicChangeEvent event) {
        switch (event.getId()) {

//            case (MusicPlayerStatusChangedEvent.PLAYER_ERROR):
//                new ErrorDialog(this, "Unexpected Player Error", event.getMsg(), false);
//                break;
//            case (PlayerBasicChangeEvent.PLAYER_DISCONNECTED):
//                new ErrorDialog(this, "Player Disconnected", event.getMsg(), false);
//                break;
            case (PlayerBasicChangeEvent.PLAYER_BITRATE_CHANGE):
                try {
                    getSongInfoPanel().setBitrate(getPlayer().getBitrate());
                } catch (MPDConnectionException ex) {
                    Logger.getLogger(MainFramePlayerTop.class.getName()).log(Level.SEVERE, null, ex);
                } catch (MPDPlayerException ex) {
                    Logger.getLogger(MainFramePlayerTop.class.getName()).log(Level.SEVERE, null, ex);
                }
                break;
        }
    }

    private void setSongInfo(MPDSong song) {
        getSongInfoPanel().setSongInfo(song);
    }

    @Override
    public void makeActions() {
        this.prevAction = new PrevAction(getPlayer());
        this.playAction = new PlayAction(getPlayer());
        this.stopAction = new StopAction(getPlayer());
        this.pauseAction = new PauseAction(getPlayer());
        this.nextAction = new NextAction(getPlayer());
    }

    @Override
    public void addGuitarPanel() {
        guitarTabPanel = new BJJPanel();
        guitarPanel = new GuitarPanel();
        guitarTabPanel.setLayout(new java.awt.BorderLayout());
        guitarTabPanel.add(guitarPanel, java.awt.BorderLayout.CENTER);
        mainTabbedPane.insertTab("Guitar", null, guitarTabPanel, null, 4);
    }

    @Override
    public void createGUI() {
        initComponents();
    }

    /**
     * @return the retracting
     */
    public boolean isRetracting() {
        return retracting;
    }

    /**
     * @param retracting the retracting to set
     */
    private void setRetracting(boolean retracting) {
        this.retracting = retracting;
    }

    @Override
    public void setMinimizePanel() {
        minimizePanel = jPanel1;
    }

    public SongInfoPanel getSongInfoPanel() {
        return (SongInfoPanel) songInfoPanel;
    }

    @Override
    public void playlistChanged(PlaylistChangeEvent event) {

        String msg = "";
        switch (event.getId()) {
            case PlaylistChangeEvent.SONG_ADDED:
            case PlaylistChangeEvent.ALBUM_ADDED:
            case PlaylistChangeEvent.ARTIST_ADDED:
            case PlaylistChangeEvent.GENRE_ADDED:
            case PlaylistChangeEvent.YEAR_ADDED:
            case PlaylistChangeEvent.FILE_ADDED:
                msg = event.getMsg();
                break;
            case PlaylistChangeEvent.MULTIPLE_SONGS_ADDED:
                msg = Utils.getMessage("RETRACT_MULTIPLE_SONGS", new String[]{event.getMsg()});
                break;
        }

        if (!"".equalsIgnoreCase(msg)) {
            songPanelRetract.setInfo(msg);

            retractPanel();
        }
    }

    private PlaylistPanel getPlaylistPanel() {
        return (PlaylistPanel) playlistPanel;
    }

    /**
     * @return the currentlyRetracting
     */
    public boolean isCurrentlyRetracting() {
        return currentlyRetracting;
    }

    /**
     * @param currentlyRetracting the currentlyRetracting to set
     */
    public void setCurrentlyRetracting(boolean currentlyRetracting) {
        this.currentlyRetracting = currentlyRetracting;
    }

    public static Frame getFrame() {
        return parent;
    }

    @Override
    public void lafChanged(LAFChangeEvent event) {
        try {
            UIManager.setLookAndFeel(StartUpProperties.getInstance().getLAFClassName());
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(StartupFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(StartupFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(StartupFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(StartupFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
        SwingUtilities.updateComponentTreeUI(this);
        pack();
    }
}
